import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  Query,
  UseGuards
} from '@nestjs/common'
import { MenuService } from './menu.service'
import { OperationService } from '../operation/operation.service'
import { CreateMenuDto, CreateMenuPermissionDto } from './dto/create-menu.dto'
import {
  BindOperationDto,
  UpdateMenuDto,
  UpdateMenuPermissionDto
} from './dto/update-menu.dto'
import { ResponseMsg } from 'src/common/custom.decorator'
import { LoggerGuard } from 'src/logger/logger.guard'

@Controller('auth/menu')
export class MenuController {
  constructor(
    private readonly menuService: MenuService,
    private readonly operationService: OperationService
  ) {}

  /**
   * @description 新增菜单
   * @param CreateMenuDto
   * @returns 创建的操作信息
   */
  @Post('create')
  @ResponseMsg('新增菜单')
  @UseGuards(LoggerGuard)
  create(@Body() createMenuDto: CreateMenuDto) {
    return this.menuService.create(createMenuDto)
  }

  /**
   * @description 获取所有菜单
   * @returns 菜单列表
   */
  @Get('list')
  @ResponseMsg('查询菜单')
  findAll() {
    return this.menuService.findAll()
  }

  /**
   * @description 根据ID查询单个菜单
   * @param id - 菜单ID
   * @returns 菜单信息
   */
  @Get('detail')
  findOne(@Query('id') id: string) {
    return this.menuService.findOne(+id)
  }

  /**
   * @description 更新菜单信息
   * @param id - 菜单ID
   * @param updateOperationDto - 包含更新信息的数据传输对象
   * @returns 更新后的菜单信息
   */
  @Patch('update')
  @ResponseMsg('更新菜单')
  @UseGuards(LoggerGuard)
  update(@Body() updateMenuDto: UpdateMenuDto) {
    return this.menuService.update(updateMenuDto)
  }

  /**
   * @description 删除菜单
   * @param id - 菜单ID
   * @returns 删除结果信息
   */
  @Delete('delete')
  @ResponseMsg('删除菜单')
  @UseGuards(LoggerGuard)
  remove(@Query('id') id: string) {
    return this.menuService.remove(+id)
  }

  /**
   * @description 根据menuId查询菜单下可选的操作列表
   * @param menuId - 查询条件
   * @returns {Array<Operation>， bindOperationIds} 操作列表以及和菜单绑定的可操作id列表
   */
  @Get('findCanOperationByMenuId')
  async findCanOperationByMenuId(@Query('menuId') menuId: number) {
    const [opertaionData, bindOperationCodes] = await Promise.all([
      this.operationService.findAll(),
      this.menuService.findCanOperationIdsByMenuId(menuId)
    ])

    return {
      operationList: opertaionData.list,
      bindOperationCodes
    }
  }

  /**
   * @description 根据menuId查询菜单下可进行的操作列表
   * @param menuId - 查询条件
   * @returns 菜单列表
   */
  @Get('findMenuBindOperations')
  @ResponseMsg('查询菜单下可进行的操作列表')
  async findMenuBindOperations(
    @Query('menuId') menuId: number,
    @Query('roleId') roleId: number
  ) {
    const [bindOperationCodes, operationList] = await Promise.all([
      this.menuService.findBindOperationsByMenuId(roleId, menuId),
      this.menuService.findCanOperationsByMenuId(menuId)
    ])

    return { bindOperationCodes, operationList }
  }

  /**
   * @description 根据menuId查询菜单下的接口权限
   * @param menuId - 查询条件
   * @param roleId - 查询条件
   * @returns 菜单列表
   */
  @Get('findMenuBindPermissions')
  @ResponseMsg('查询菜单接口权限')
  async findMenuBindPermissions(
    @Query('menuId') menuId: number,
    @Query('roleId') roleId: number
  ) {
    const [binds, list] = await Promise.all([
      this.menuService.findBindPermissionByMenuId(roleId, menuId),
      this.menuService.findMenuPermission(menuId)
    ])
    return { binds, list }
  }

  /**
   * @description 绑定菜单和操作
   * @param bindDto - 包含菜单ID和操作ID的数据传输对象
   * @returns 绑定结果信息
   */
  @Post('bindMenuOpeation')
  @ResponseMsg('菜单分配操作')
  @UseGuards(LoggerGuard)
  bindMenuOpeation(@Body() bindDto: BindOperationDto) {
    return this.menuService.bindMenuOpeation(bindDto)
  }

  /**
   * @description 查询菜单接口权限
   * @returns 菜单接口
   */
  @Get('permission')
  @ResponseMsg('查询菜单接口权限')
  async findPermission(
    @Query('menuId') menuId: number,
    @Query('keyword') keyword: string
  ) {
    return this.menuService.findMenuPermission(menuId, keyword)
  }

  @Post('permission/create')
  @ResponseMsg('新增接口权限')
  createMenuPermission(@Body() createPermissionDto: CreateMenuPermissionDto) {
    return this.menuService.createMenuPermission(createPermissionDto)
  }

  @Patch('permission/update')
  @ResponseMsg('更新接口权限')
  updateMenuPermission(@Body() updatePermissionDto: UpdateMenuPermissionDto) {
    return this.menuService.updateMenuPermission(updatePermissionDto)
  }

  @Delete('permission/delete')
  @ResponseMsg('删除接口权限')
  removeMenuPermission(@Query('id') id: number) {
    return this.menuService.removeMenuPermission(id)
  }
}
